package com.yuandian.business.monitor.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.yuandian.api.business_monitor.po.ClientAnalysisParams;
import com.yuandian.api.business_monitor.vo.BrowserVo;
import com.yuandian.api.business_monitor.vo.OperatingSystemVo;
import com.yuandian.business.monitor.mapper.ClientAnalysisMapper;
import com.yuandian.business.monitor.service.IClientAnalysisService;
import com.yuandian.utils.MathUtil;
import com.yuandian.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 客户端分析
 *
 * @Author LinShiHe
 * @Date 2023/5/25
 */
@Slf4j
@Service
public class ClientAnalysisServiceImpl implements IClientAnalysisService {

	@Autowired
	private ClientAnalysisMapper clientAnalysisMapper;


	/**
	 * 获取各操作系统对应的访问量
	 *
	 * @param params 参数
	 * @return 通用返回对象
	 */
	@Override
	public List<OperatingSystemVo> getOperatingSystemData(ClientAnalysisParams params) {
		// 处理请求参数
		if (StringUtils.isNotEmpty(params.getOperatingSystem()) && "其它".equals(params.getOperatingSystem())) {
			params.setOperatingSystem("Unknow");
		}

		// 查询数据
		List<OperatingSystemVo> dataList = clientAnalysisMapper.getOperatingSystemData(params);
		List<OperatingSystemVo> resultList = new ArrayList<>();

		if (CollectionUtil.isNotEmpty(dataList)) {
			Map<String, OperatingSystemVo> voMap = new HashMap<>();

			for (OperatingSystemVo vo : dataList) {
				Map<String, String> map = cutData(vo.getOperatingSystem());
				// 对数据 浏览器 字段进行切割, 取 浏览器名称 或 浏览器版本
				String key = StringUtils.isNotEmpty(params.getOperatingSystem()) ? map.get("version") : map.get("name");

				// 对列表数据进行聚合统计
				voMap.computeIfAbsent(key, k -> new OperatingSystemVo());

				OperatingSystemVo operatingSystemVo = voMap.get(key);
				operatingSystemVo.setOperatingSystem(key);
				operatingSystemVo.setVisitCount(operatingSystemVo.getVisitCount() == null ? vo.getVisitCount() : (vo.getVisitCount() + operatingSystemVo.getVisitCount()));
				operatingSystemVo.setDealTime(operatingSystemVo.getDealTime() == null ? vo.getDealTime() : (vo.getDealTime() + operatingSystemVo.getDealTime()));
				voMap.put(key, operatingSystemVo);
			}

			for (OperatingSystemVo vo : voMap.values()) {
				// 求平均处理时长 (单位: 毫秒)
				vo.setAvgDealTime(vo.getVisitCount() != 0 ? (vo.getDealTime() / vo.getVisitCount()) : 0);
				// 对 UnKnow System 进行处理
				if (containsIgnoreCase(vo.getOperatingSystem(), "unknow")) {
					vo.setOperatingSystem("其它");
				}
				resultList.add(vo);
			}

			// 如果是查询某系统对应各个版本的明细数据，则对版本进行排序
			if (StringUtils.isNotEmpty(params.getOperatingSystem())) {
				resultList.sort((o1, o2) -> {
					// 版本可能不为数字
					if (MathUtil.isNumeric(o1.getOperatingSystem()) && MathUtil.isNumeric(o2.getOperatingSystem())) {
						double diff = Double.parseDouble(o1.getOperatingSystem()) - Double.parseDouble(o2.getOperatingSystem());
						return diff == 0 ? 0 : (diff > 0 ? 1 : -1);
					} else {
						return -1;
					}
				});
			}
		}

		return resultList;
	}



	/**
	 * 获取各浏览器维度的访问量 和 处理时长
	 *
	 * @param params 参数
	 * @return 通用返回对象
	 */
	@Override
	public List<BrowserVo> getBrowserData(ClientAnalysisParams params) {
		// 处理请求参数
		if (StringUtils.isNotEmpty(params.getBrowser()) && "其它".equals(params.getBrowser())) {
			params.setBrowser("Unknow");
		}

		// 查询数据
		List<BrowserVo> dataList = clientAnalysisMapper.getBrowserData(params);
		List<BrowserVo> resultList = new ArrayList<>();

		if (CollectionUtil.isNotEmpty(dataList)) {
			Map<String, BrowserVo> voMap = new HashMap<>();

			for (BrowserVo vo : dataList) {
				Map<String, String> map = cutData(vo.getBrowser());
				// 对数据 操作系统 字段进行切割, 取 系统名称 或 系统版本
				String key = StringUtils.isNotEmpty(params.getBrowser()) ? map.get("version") : map.get("name");

				// 对列表数据进行聚合统计
				voMap.computeIfAbsent(key, k -> new BrowserVo());

				BrowserVo browserVo = voMap.get(key);
				browserVo.setBrowser(key);
				browserVo.setVisitCount(browserVo.getVisitCount() == null ? vo.getVisitCount() : (vo.getVisitCount() + browserVo.getVisitCount()));
				browserVo.setDealTime(browserVo.getDealTime() == null ? vo.getDealTime() : (vo.getDealTime() + browserVo.getDealTime()));
				voMap.put(key, browserVo);
			}

			for (BrowserVo vo : voMap.values()) {
				// 求平均处理时长 (单位: 毫秒)
				vo.setAvgDealTime(vo.getVisitCount() != 0 ? (vo.getDealTime() / vo.getVisitCount()) : 0);
				// 对 UnKnow Browser 进行处理
				if (containsIgnoreCase(vo.getBrowser(), "unknow")) {
					vo.setBrowser("其它");
				}
				resultList.add(vo);
			}

			// 如果是查询某浏览器对应各个版本的明细数据，则对版本进行排序
			if (StringUtils.isNotEmpty(params.getBrowser())) {
				resultList.sort((o1, o2) -> {
					// 版本可能不为数字
					if (MathUtil.isNumeric(o1.getBrowser()) && MathUtil.isNumeric(o2.getBrowser())) {
						double diff = Double.parseDouble(o1.getBrowser()) - Double.parseDouble(o2.getBrowser());
						return diff == 0 ? 0 : (diff > 0 ? 1 : -1);
					} else {
						return -1;
					}
				});
			}
		}

		return resultList;
	}


	/**
	 * 切割字符串，获取 (操作系统/浏览器)名称 以及 版本
	 * @param fieldName	待切割字段
	 * @return 结果集
	 */
	private static Map<String, String> cutData(String fieldName) {
		Map<String, String> map = new HashMap<>();
		if (StringUtils.isNotEmpty(fieldName)) {
			String[] s = fieldName.split(" ");
			if (containsIgnoreCase(fieldName, "unknow")) {
				map.put("name", fieldName);
				map.put("version", fieldName);
			} else {
				map.put("name", s[0]);
				map.put("version", s[s.length - 1]);
			}
		}
		return map;
	}



	/**
	 * 判断 str 里是否包含 subString
	 * @param str			父字符串
	 * @param subString		子字符串
	 * @return 结果集
	 */
	public static boolean containsIgnoreCase(String str, String subString) {
		return str.toLowerCase().contains(subString.toLowerCase());
	}

}
